#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Filename: xmind_to_tapd_ui.py
# Author: ChenChangSong
# Date: 2025-08-24

"""
功能描述: XMind→TAPD 页面 UI。
"""
import json
from pathlib import Path
from PyQt5.QtWidgets import (
    QFileDialog,      # 文件对话框，用于选择文件
    QGridLayout,      # 网格布局
    QHBoxLayout,      # 水平布局
    QLabel,           # 标签控件
    QLineEdit,        # 单行文本编辑框
    QPushButton,      # 按钮控件
    QSpinBox,         # 数字调节框
    QVBoxLayout,      # 垂直布局
    QWidget,          # 基础窗口部件
    QMessageBox,      # 消息框
    QToolButton,      # 工具按钮
    QDialog,          # 对话框
    QTextBrowser,     # 文本浏览器
)
from PyQt5.QtGui import QPixmap, QFont
from PyQt5.QtCore import Qt

from .common_ui import LogPanel, InfoWithImageDialog, get_project_root  # 导入日志面板组件和项目根目录函数

# 定义配置文件路径
CONFIG_PATH = get_project_root() / "files" / "config_file" / "dir_level_settings.json"


class XMindToTapdPage(QWidget):
    def __init__(self) -> None:
        super().__init__()
        self._init_ui()

    def _init_ui(self) -> None:
        """初始化用户界面，保持与XMindToExcelPage布局一致"""
        # 创建根布局（垂直布局）
        root = QVBoxLayout(self)
        root.setSpacing(10)  # 设置布局内控件间距
        root.setContentsMargins(10, 10, 10, 10)  # 增加根布局边距

        # 添加说明标签和问号图标
        info_hbox = QHBoxLayout()
        info_hbox.setSpacing(5)
        
        # 说明标签
        info_label = QLabel("说明！此处的功能是通过API将选择的XMind脑图用例导入到TAPD（手动导入见：XMind→Excel）。\n"
             "注意：1、目录层级尽量全部保留，方便以后直接从tapd导出为XMind脑图。2、脑图中的需求ID要19位的哦！")
        
        # 问号图标按钮 - 使用与login_ui类似的实现方式
        question_btn = self._help_btn()
        
        # 获取图片路径
        image_path = get_project_root() / "files" / "software_image_icon" / "需求ID_19位.png"
        
        # 设置悬浮提示和点击事件
        img_url = image_path.as_uri()
        title = "需求ID说明"
        text = "此处是通过API导入TAPD，注意需求ID要用19位的如图："
        
        # 悬浮直接展示与点击相同的图文内容
        html_tooltip = f"<b>{title}</b><br/>{text}<br/><img src='{img_url}' width='320'/>"
        question_btn.setToolTip(html_tooltip)
        
        # 点击弹窗
        question_btn.clicked.connect(lambda _=None, t=title, m=text, p=image_path: InfoWithImageDialog(t, m, p).exec_())
        
        info_hbox.addWidget(info_label)
        info_hbox.addWidget(question_btn)
        info_hbox.addStretch()  # 添加伸缩项使内容靠左
        root.addLayout(info_hbox)

        # 创建网格布局用于排列控件
        grid = QGridLayout()
        grid.setHorizontalSpacing(5)  # 水平间距与Excel页面一致
        grid.setVerticalSpacing(8)    # 垂直间距与Excel页面一致
        grid.setContentsMargins(5, 5, 5, 5)  # 网格布局内部边距

        # 文件路径显示框
        self.input_file = QLineEdit()
        self.input_file.setReadOnly(True)  # 设置为只读
        self.input_file.setPlaceholderText("当前未选择XMind文件")
        self.input_file.setMinimumWidth(400)  # 保持宽度设置一致

        # 选择文件按钮
        self.btn_choose = QPushButton("选择XMind文件")
        self.btn_choose.setMinimumSize(120, 30)  # 改用最小尺寸
        self.btn_choose.setMaximumSize(180, 30)  # 增加最大宽度冗余
        self.btn_choose.clicked.connect(self._choose_file)

        # 目录层级选择器
        self.spin_level = QSpinBox()
        self.spin_level.setRange(3, 99)  # 设置范围，最小值为3
        # 从配置文件读取保存的目录层级，如果没有则使用默认值99
        saved_level = self._get_saved_level()
        self.spin_level.setValue(saved_level)
        self.spin_level.setPrefix("保留 ")
        self.spin_level.setSuffix(" 级目录(Xmind目录层级低于此值则保留全部)")
        self.spin_level.setToolTip("只能输入大于等于3的整数")
        # 连接值改变信号，保存设置
        self.spin_level.valueChanged.connect(self._save_level_setting)

        # 导入按钮
        self.btn_import = QPushButton("XMind→TAPD")
        button_min_width = 120  # 按钮最小宽度
        button_height = 30      # 按钮高度
        self.btn_import.setMinimumSize(button_min_width, button_height)
        self.btn_import.setMaximumSize(180, button_height)

        # 创建水平布局放置导入按钮（与Excel页面的按钮布局方式一致）
        button_hbox = QHBoxLayout()
        button_hbox.setSpacing(5)  # 按钮间距与Excel页面一致
        button_hbox.addWidget(self.btn_import)

        # 将控件添加到网格布局（保持行列位置一致）
        grid.addWidget(self.btn_choose, 0, 0)  # 第0行第0列
        grid.addWidget(self.input_file, 0, 1, 1, 2)  # 第0行第1列，跨2列
        grid.addWidget(QLabel("保留目录层级:"), 1, 0)  # 添加标签
        grid.addWidget(self.spin_level, 1, 1)  # 第1行第1列
        grid.addLayout(button_hbox, 1, 2)  # 第1行第2列

        # 优化列宽策略
        grid.setColumnMinimumWidth(0, 150)  # 按钮列最小宽度
        grid.setColumnStretch(1, 1)         # 文件路径列可拉伸
        grid.setColumnStretch(2, 0)         # 辅助列不拉伸

        # 将网格布局添加到根布局
        root.addLayout(grid)

        # 添加日志面板
        self.log_panel = LogPanel()
        root.addWidget(self.log_panel)

        # 绑定导入按钮点击事件
        self.btn_import.clicked.connect(self._import_to_tapd)

    def _choose_file(self) -> None:
        """选择XMind文件的方法"""
        # 清空屏幕日志
        self.log_panel.clear_screen_logs()
        path, _ = QFileDialog.getOpenFileName(self, "选择XMind文件", "", "XMind (*.xmind)")
        if path:
            self.input_file.setText(path)

    def _import_to_tapd(self) -> None:
        """导入到TAPD的方法"""
        if not self.input_file.text():
            QMessageBox.warning(self, "提示", "请先选择XMind文件")
            return
        
        # 获取选择的文件路径和目录层级
        xmind_path = self.input_file.text()
        level = self.spin_level.value()
        
        # 导入xmind_to_tapd_add函数
        from function_code.xmind_to_tapd.xmind_to_tapd_add import xmind_to_tapd_add
        
        # 调用xmind_to_tapd_add方法，将选择的xmind文件路径和目录层级作为参数传递
        xmind_to_tapd_add(xmind_path, level)
        
    def _get_saved_level(self) -> int:
        """从配置文件读取保存的目录层级设置"""
        try:
            # 确保配置文件目录存在
            CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
            
            # 如果配置文件存在，读取设置
            if CONFIG_PATH.exists():
                with open(CONFIG_PATH, 'r', encoding='utf-8') as f:
                    settings = json.load(f)
                    return settings.get('to_tapd_dir_level', 99)
        except Exception:
            # 读取失败时使用默认值
            pass
        return 99
    
    @staticmethod
    def _help_btn() -> QToolButton:
        """创建问号帮助按钮，与login_ui.py保持一致"""
        btn = QToolButton()
        btn.setText("❓")
        btn.setAutoRaise(True)
        btn.setToolTip("查看填写说明与示例图")
        return btn
        
    def _save_level_setting(self, value: int) -> None:
        """保存目录层级设置到配置文件"""
        try:
            # 确保配置文件目录存在
            CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
            
            # 读取现有设置
            settings = {}
            if CONFIG_PATH.exists():
                try:
                    with open(CONFIG_PATH, 'r', encoding='utf-8') as f:
                        settings = json.load(f)
                except Exception:
                    # 读取失败时使用空字典
                    pass
            
            # 更新设置
            settings['to_tapd_dir_level'] = value
            
            # 保存设置
            with open(CONFIG_PATH, 'w', encoding='utf-8') as f:
                json.dump(settings, f, ensure_ascii=False, indent=2)
        except Exception:
            # 保存失败时静默处理，不影响用户使用
            pass